package com.zis.platform.core.service.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Appender;
import org.apache.log4j.DailyRollingFileAppender;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zis.common.SearchParams;
import com.zis.platform.common.log.LoginLogAspect;
import com.zis.platform.common.log.OperationLogAspect;
import com.zis.platform.common.service.impl.BaseServiceImpl;
import com.zis.platform.core.dao.LogLoginDao;
import com.zis.platform.core.dao.LogOpterationDao;
import com.zis.platform.core.entity.LogLoginEntity;
import com.zis.platform.core.entity.LogOpterationEntity;
import com.zis.platform.core.service.LogLoginService;
import com.zis.util.DateUtils;
import com.zis.util.StringUtil;

@Service
public class LogLoginServiceImpl extends BaseServiceImpl<LogLoginEntity> implements LogLoginService
{
    protected transient Logger logger = Logger.getLogger(getClass());
    
    // 操作日志标示
    private static final String OPTERATION_LOG_APPENDER_ID = "A2";
    
    // 登录日志 标示
    private static final String LOGIN_LOG_APPENDER_ID = "A3";
    
    // 日志文件后缀名
    private static final String LOG_FILE_EXE = ".log";
    
    @Autowired
    private LogLoginDao dao;
    
    @Autowired
    private LogOpterationDao optDao;
    
    @Override
    public List<LogLoginEntity> findByCondition(SearchParams params)
        throws Exception
    {
        return dao.findByCondition(params);
    }
    
    @Override
    public List<LogLoginEntity> findAll()
        throws Exception
    {
        return dao.findAll();
    }
    
    @Override
    public void save(LogLoginEntity log)
    {
        if (StringUtil.isEmpty(log.getLogId()))
        {
            log.setLogId(UUID.randomUUID().toString());
        }
        dao.insert(log);
    }
    
    @Override
    public void parseLogFromFile(String type, String startDate, String endDate)
    {
        try
        {
            Date parseStartDate = DateUtils.parse(startDate, "yyyy-MM-dd");
            Date parseEndDate = DateUtils.parse(endDate, "yyyy-MM-dd");
            int dayNum = DateUtils.getDaysBetweenDate(parseStartDate, parseEndDate) + 1;
            for (int i = 0; i < dayNum; i++)
            {
                if ("login".equals(type))
                {
                    parseLoginLogFileAndInsertDB(parseStartDate);
                }
                else
                {
                    parseOpterationLogFileAndInsertDB(parseStartDate);
                }
                parseStartDate = DateUtils.getSpecficDateStart(parseStartDate, 1);
            }
        }
        catch (ParseException e)
        {
            e.printStackTrace();
        }
    }
    
    /**
     * 解析登录日志文件内容并将数据插入到数据库,如果文件存在并全部解析完则返回true 否则 false
     * 
     * @return boolean
     */
    private boolean parseLoginLogFileAndInsertDB(Date parseStartDate)
    {
        
        String logFilePath = "";
        if (DateUtils.getDaysBetweenDate(parseStartDate, new Date()) == 0)
        {
            logFilePath = getLoginLogFile().getAbsolutePath();
        }
        else
        {
            logFilePath =
                getLoginLogFile().getAbsolutePath() + "-" + DateUtils.format(parseStartDate, "yyyy-MM-dd")
                    + LOG_FILE_EXE;
        }
        File log = new File(logFilePath);
        if (log.exists())
        {
            try
            {
                FileReader fileReader = new FileReader(log);
                BufferedReader reader = new BufferedReader(fileReader);
                String lineTxt = "";
                ObjectMapper mapper = new ObjectMapper();
                while ((lineTxt = reader.readLine()) != null)
                {
                    try
                    {
                        LogLoginEntity loginLog = mapper.readValue(lineTxt, LogLoginEntity.class);
                        if (StringUtils.isNotEmpty(loginLog.getLogId()))
                        {
                            LogLoginEntity logDB = dao.selectByPrimaryKey(loginLog.getLogId());
                            if (logDB == null)
                            {
                                dao.insert(loginLog);
                            }
                        }
                    }
                    catch (com.fasterxml.jackson.core.JsonParseException e)
                    {
                    }
                    catch (com.fasterxml.jackson.databind.JsonMappingException e)
                    {
                    }
                }
            }
            catch (FileNotFoundException e)
            {
                e.printStackTrace();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            return true;
        }
        else
        {
            return false;
        }
    }
    
    /**
     * 解析登录日志文件内容并将数据插入到数据库,如果文件存在并全部解析完则返回true 否则 false
     * 
     * @return boolean
     */
    private boolean parseOpterationLogFileAndInsertDB(Date parseStartDate)
    {
        
        String logFilePath = "";
        if (DateUtils.getDaysBetweenDate(parseStartDate, new Date()) == 0)
        {
            logFilePath = getOpterationLogFile().getAbsolutePath();
        }
        else
        {
            logFilePath =
                getOpterationLogFile().getAbsolutePath() + "-" + DateUtils.format(parseStartDate, "yyyy-MM-dd")
                    + LOG_FILE_EXE;
        }
        File log = new File(logFilePath);
        if (log.exists())
        {
            try
            {
                FileReader fileReader = new FileReader(log);
                BufferedReader reader = new BufferedReader(fileReader);
                String lineTxt = "";
                ObjectMapper mapper = new ObjectMapper();
                while ((lineTxt = reader.readLine()) != null)
                {
                    try
                    {
                        LogOpterationEntity optLog = mapper.readValue(lineTxt, LogOpterationEntity.class);
                        if (StringUtils.isNotEmpty(optLog.getLogId()) && StringUtils.isNotEmpty(optLog.getOptUser()))
                        {
                            LogOpterationEntity logDB = optDao.selectByPrimaryKey(optLog.getLogId());
                            if (logDB == null)
                            {
                                optDao.insertSelective(optLog);
                            }
                        }
                    }
                    catch (com.fasterxml.jackson.core.JsonParseException e)
                    {
                    }
                    catch (com.fasterxml.jackson.databind.JsonMappingException e)
                    {
                    }
                }
            }
            catch (FileNotFoundException e)
            {
                e.printStackTrace();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            return true;
        }
        else
        {
            return false;
        }
    }
    
    // 获取当前的登录日志文件
    private File getLoginLogFile()
    {
        Logger log = Logger.getLogger(LoginLogAspect.class);
        Appender appender = log.getAppender(LOGIN_LOG_APPENDER_ID);
        return new File(((DailyRollingFileAppender)appender).getFile());
    }
    
    // 获取当前的操作日志文件
    private File getOpterationLogFile()
    {
        Logger log = Logger.getLogger(OperationLogAspect.class);
        Appender appender = log.getAppender(OPTERATION_LOG_APPENDER_ID);
        return new File(((DailyRollingFileAppender)appender).getFile());
    }
}
